﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using SharpBolt.Basics;
using SharpBolt;
using InductBase;
using SharpBolt.Graphics;
using SharpBolt.Graphics;
using SharpBolt.Graphics.GraphicSources;
using SharpBolt.Graphics.GraphicInstances;

using SharpBolt.Sound;
using SharpBolt.Input;

using InductBase.Extensions;

using PowerOne;
using PowerOne.GraphicUtilites;
using PowerOne.SoundUtilites;
using PowerOne.InputUtilites;

namespace PowerOne
{
    public class PowerWindow : GameWindow
    {
        public PowerWindow()
            : base(640, 480, GraphicsMode.Default, "Test Game", GameWindowFlags.Default)
        {
            BuildEngine();
        }

        private void BuildEngine()
        {
            VSync = VSyncMode.Adaptive;

            Engine.GraphicRender = new OpenGLRender();
            (Engine.GraphicRender as OpenGLRender).GameWindow = this;
            //this.TargetRenderFrequency = 1;
            this.TargetUpdateFrequency = 1;
            this.VSync = VSyncMode.Off;

            Engine.Miscs = new Miscs();
            Engine.DefaultPainter = new Painter(Engine.GraphicRender);
            Engine.TimeManager = new SharpBolt.Time.TimeManager();
            Engine.SoundRender = new KlangSoundRender();
            Engine.InputObserver = new InputObserver();
            Engine.TweeningManager = new SharpBolt.Tweening.TweeningManager(Engine.TimeManager);
        }

        protected override void OnLoad(EventArgs E)
        {
            base.OnLoad(E);
            LoadEngine();
        }

        private void LoadEngine()
        {
            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
            
            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
            
            Engine.GraphicRender.ScreenSize = this.Size.ToVec2i();

            OpenTKInputProvider inputProvider;
            inputProvider = new OpenTKInputProvider();
            inputProvider.AttachToKeyboard(Keyboard);
            inputProvider.AttachToMouse(Mouse);

            Engine.InputObserver.AttachInputProvider(inputProvider);
        }

        protected override void OnResize(EventArgs E)
        {
            base.OnResize(E);
            OnResizeEngine();
        }

        private void OnResizeEngine()
        {
            Engine.GraphicRender.ScreenSize = new Vec2i(ClientRectangle.Width, ClientRectangle.Height);
            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
        }

        protected override void OnUpdateFrame(FrameEventArgs E)
        {
            base.OnUpdateFrame(E);
            UpdateEngine(); 
        }

        private static void UpdateEngine()
        {
            Engine.TimeManager.Update();
            Engine.InputObserver.UpdateKeysState();
            Engine.InputObserver.UpdateManipulators();
            Engine.TweeningManager.Update();
        }

        protected override void OnRenderFrame(FrameEventArgs E)
        {
            base.OnRenderFrame(E);
        }
    }
}
